/**
 * toast 提示
 * @param {String} title - 提示标题
 * @param {Object} param - 提示参数配置
 * @param {Number} param.duration - 显示时长，默认1500ms
 * @param {Boolean} param.mask - 是否显示遮罩，默认false
 * @param {String} param.icon - 图标类型，默认'none'
 */
export const msg = (title = '', param={}) => {
    if(!title) return;
    uni.showToast({
        title,
        duration: param.duration || 1500,
        mask: param.mask || false,
        icon: param.icon || 'none'
    });
}

/**
 * 检查登录状态
 * @param {Object} options - 配置选项
 * @param {*} options.nav - 导航控制，传false时不跳转登录页
 * @return {Boolean} 是否已登录
 */
export const isLogin = (options={}) => {
    const token = uni.getStorageSync('mxgEducationToken');
    // 如果存在token，则表示已登录
    if(token){ // 加上!先暂时表示已经登录
        return true;
    }
    // options.nav只要传的不是 false，默认跳转到登录页
    // 如果nav参数不为false，则跳转到登录页面
    if(options.nav !== false){
        console.log('options.nav', options.nav)
        // 导航到登录页面
        uni.navigateTo({
            url: '/pages/auth/login'
        })
    }
    return false;
}

// 节流状态标志，防止多次请求同时执行
let _throttleRunning = false

/**
 * 节流函数，防止函数在指定时间内重复执行
 * @param {Function} fn - 需要节流执行的函数
 * @param {Number} delay - 延时时间，单位毫秒，默认500ms
 */
export const throttle = (fn, delay=500) => {
    // 如果正在运行中，则直接返回，不执行本次调用
    if(_throttleRunning){
        return;
    }
    // 标识函数正在运行中
    _throttleRunning = true;

    // 延时delay毫秒后执行函数，并在执行完成后重置运行状态
    setTimeout(() => {
        fn();                           
        _throttleRunning = false;       
    }, delay);
}

/**
 * 获取当前页面的路由地址及参数
 * @returns {String} 当前页面路由地址+参数
 */
export const routePath = () => {
    // 获取所有页面栈对象数组
    const pages = getCurrentPages();
    // 获取当前页面实例（页面栈中的最后一个）
    const page = pages[pages.length - 1];

    // 获取当前路由参数对象
    // 在小程序或app中，使用 page.options ; H5端使用 page.$route.query
    const query = page.options || page.$route.query;
    // 将参数对象转换为 key1=value1&key2=value2 形式的查询字符串
    let queryStr = '';
    // 如果存在查询参数，则遍历所有键值对进行拼接
    query && Object.keys(query).forEach((key)=>{
        queryStr += `${key}=${query[key]}`
    });
    // 返回当前路由地址+参数，如果没有参数则只返回路由地址
    return queryStr ? `${page.route}?${queryStr}`: page.route;
}

/**
 * 校验数据格式
 * @param {String} str - 需要校验的数据
 * @param {String} type - 数据格式类型
 * @returns {Boolean} 校验结果
 */
export const checkStr = (str, type) => {
    // 根据不同类型进行相应的正则表达式校验
    switch (type) {
        case 'mobile': //手机号码
            return /^1[3|4|5|6|7|8|9][0-9]{9}$/.test(str);
        case 'tel': //座机
            return /^(0\d{2,3}-\d{7,8})(-\d{1,4})?$/.test(str);
        case 'card': //身份证
            return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(str);
        case 'mobileCode': //6位数字验证码
            return /^[0-9]{6}$/.test(str)
        case 'pwd': //密码以字母开头，长度在6~18之间，只能包含字母、数字和下划线
            return /^([a-zA-Z0-9_]){6,18}$/.test(str)
        case 'payPwd': //支付密码 6位纯数字
            return /^[0-9]{6}$/.test(str)
        case 'postal': //邮政编码
            return /[1-9]\d{5}(?!\d)/.test(str);
        case 'QQ': //QQ号
            return /^[1-9][0-9]{4,9}$/.test(str);
        case 'weixin': //微信号
            return /^[a-zA-Z][a-zA-Z\d_-]{5,19}$/.test(str);
        case 'email': //邮箱
            return /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(str);
        case 'money': //金额(小数点2位)
            return /^\d*(?:\.\d{0,2})?$/.test(str);
        case 'URL': //网址
            return /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/.test(str)
        case 'IP': //IP
            return /((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))/.test(str);
        case 'date': //日期时间
            return /^(\d{4})\-(\d{2})\-(\d{2}) (\d{2})(?:\:\d{2}|:(\d{2}):(\d{2}))$/.test(str) || /^(\d{4})\-(\d{2})\-(\d{2})$/
                .test(str)
        case 'number': //数字
            return /^[0-9]$/.test(str);
        case 'english': //英文
            return /^[a-zA-Z]+$/.test(str);
        case 'chinese': //中文
            return /^[\\u4E00-\\u9FA5]+$/.test(str);
        case 'lower': //小写
            return /^[a-z]+$/.test(str);
        case 'upper': //大写
            return /^[A-Z]+$/.test(str);
        case 'HTML': //HTML标记
            return /<("[^"]*"|'[^']*'|[^'">])*>/.test(str);
        default:
            // 默认返回true
            return true;
    }
}

/**
 * 格式化日期字符串，根据时间差显示不同的友好格式
 * @param {Number} date - 日期时间戳或日期字符串
 * @returns {String} 格式化后的日期字符串
 */
export const dateFormat = (date)=>{
    // 如果没有日期参数则返回空字符串
    if(!date) return ''
    // 处理iOS Safari浏览器的日期兼容性问题
    // ? 兼容 ios safari : 兼容其他浏览器
    let $this = new Date( date ) == 'Invalid Date' ? new Date( date.replace(/-/g,"/") ) : new Date(date)
    // 获取时间戳并转换为秒
    var timestamp = parseInt(Date.parse($this)) / 1000 //- 8 * 60 * 60; //（本地时间）东八区减去8小时;

    // 补零函数，个位数前面补0
    function zeroize( num ) {
		 return (String(num).length == 1 ? '0' : '') + num;
    }
    // 获取当前时间戳（秒）
    var curTimestamp = parseInt(new Date().getTime() /1000); //当前时间戳
    // 计算时间差（秒）
    var timestampDiff = curTimestamp - timestamp; // 参数时间戳与当前时间戳相差秒数
    // 创建当前时间和参数时间的日期对象
    var curDate = new Date( curTimestamp * 1000 ); // 当前时间日期对象
    var tmDate = new Date( timestamp * 1000 );  // 参数时间戳转换成的日期对象

    // 获取年月日时分秒
    var Y = tmDate.getFullYear(), m = tmDate.getMonth() + 1, d = tmDate.getDate();
    var H = tmDate.getHours(), i = tmDate.getMinutes(), s = tmDate.getSeconds();

    // 根据时间差返回不同的友好显示格式
    if ( timestampDiff < 60 ) { // 一分钟以内
            return "刚刚";
    } else if( timestampDiff < 3600 ) { // 一小时前之内
            return Math.floor( timestampDiff / 60 ) + "分钟前";
    } else if ( curDate.getFullYear() == Y && curDate.getMonth()+1 == m && curDate.getDate() == d ) {
            // 今天显示具体时间
            return '今天 ' + zeroize(H) + ':' + zeroize(i) + ':' + zeroize(s);
    } else {
            // 创建前一天的日期对象
            var newDate = new Date( (curTimestamp - 86400) * 1000 ); // 参数中的时间戳加一天转换成的日期对象
            if ( newDate.getFullYear() == Y && newDate.getMonth()+1 == m && newDate.getDate() == d ) {
                    // 昨天显示具体时间
                    return '昨天 ' + zeroize(H) + ':' + zeroize(i) + ':' + zeroize(s);
            } else if ( curDate.getFullYear() == Y ) {
                    // 今年的其他日期显示月日
                    // return  zeroize(m) + '月' + zeroize(d) + '日 ' + zeroize(H) + ':' + zeroize(i) + ':' + zeroize(s);
                    return  zeroize(m) + '月' + zeroize(d) + '日';
            } else {
                    // 其他年份显示年月日
                    // return  Y + '年' + zeroize(m) + '月' + zeroize(d) + '日 ' + zeroize(H) + ':' + zeroize(i) + ':' + zeroize(s);
                    return  Y + '年' + zeroize(m) + '月' + zeroize(d) + '日';
            }
    }
}

/**
 * 格式化日期，按照指定格式输出
 * @param {Date} date - 日期对象或日期字符串
 * @param {String} format - 转换后的日期格式，默认"yyyy-MM-dd hh:mm:ss"
 * @returns {String} 格式化后的日期字符串
 */
export function format(date, format = "yyyy-MM-dd hh:mm:ss" ){
        // 如果没有日期参数则返回空字符串
        if(!date) return ''
        // 处理iOS Safari浏览器的日期兼容性问题
        // ? 兼容safari : 兼容其他浏览器
        let $this = new Date( date ) == 'Invalid Date' ? new Date( date.substr(0, 19) ) : new Date(date)

        // 定义日期各部分的映射关系
        let o = {
            'M+': $this.getMonth() + 1,         // 月份
            'd+': $this.getDate(),              // 日
            'h+': $this.getHours(),             // 小时
            'm+': $this.getMinutes(),           // 分钟
            's+': $this.getSeconds(),           // 秒
            'q+': Math.floor(($this.getMonth() + 3) / 3), // 季度
            'S': $this.getMilliseconds()        // 毫秒
        }
        // 处理年份格式
        if (/(y+)/.test(format)) {
            format = format.replace(RegExp.$1, ($this.getFullYear() + '').substr(4 - RegExp.$1.length))
        }
        // 处理其他日期部分格式
        for (var k in o) {
            if (new RegExp('(' + k + ')').test(format)) {
                    format = format.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
            }
        }
        // 返回格式化后的日期字符串
        return format
}
